#include <iostream>
#include <string>
#include <vector>
#include <functional>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>

using namespace std; 





void PrintPending(const sigset_t& pending)
{
    cout << "curr pending list [" << getpid() << "]:"; 
    // 使用sigismember判断该信号是否在集合中
    for (int signo = 31; signo > 0; --signo)
    {
        if (sigismember(&pending, signo))
        {
            // 存在打印1
            cout << 1;
        }
        else
        {
            // 不存在打印0
            cout << 0;
        }
    }
    cout << endl;
}

int main()
{
    cout << "补笔记" << endl;
    // 捕捉信号
    signal(2, SIG_IGN);

    // 1.对2号信号屏蔽
    // 栈上开辟空间
    sigset_t block, oblock;
    // 对该结构体进行清0 sigemptyset 系统调用
    sigemptyset(&block);
    sigemptyset(&oblock);

    // 1.1 添加2号信号
    // 我们有没有把2号信号的屏蔽，设置在内核中？
    // 没有，只是在用户栈上设置了block的位图结构
    sigaddset(&block, 2);
    // 1.2 设置进入内核 覆盖设置
    sigprocmask(SIG_SETMASK, &block, &oblock);
    int cnt = 0;

    while (true)
    {
        // 2.如何获取pending表?
        sigset_t pending;
        sigpending(&pending);

        // 2.1 打印
        PrintPending(pending);
        sleep(1);

        ++cnt;
        if (cnt == 10)
        {
            cout << "解除对2号信号的屏蔽" << endl;
            // 修改为原来的block表 这次不需要将旧的保存了
            sigprocmask(SIG_SETMASK, &oblock, nullptr);
        }
    }

    return 0;
}




// void handler(int signo)
// {
//     cout << "get a new signal: " << signo << endl;
//     exit(1);
// }

// int main()
// {
//     // 信号捕捉
//     // 1. 默认
//     // 2. 忽略
//     // 3. 自定义捕捉
//     // ::signal(2, handler);
//     // ::signal(2, SIG_IGN); // 忽略 ignore
//     ::signal(2, SIG_DFL); // 默认

//     while (true)
//     {
//         pause();
//     }
//     return 0;
// }


// int main()
// {
//     if (fork() == 0)
//     {
//         // 子进程
//         sleep(1);
//         int a = 10;
//         a /= 0;
//         exit(0);
//     }

//     int status = 0;
//     waitpid(-1, &status, 0); // 阻塞等待
//     printf("exit signal: %d, core dump: %d\n", status&0x7F, (status >> 7) & 1);
//     return 0;
// }


// void handler(int signo)
// {
//     cout << "signo number is " << signo << endl;
// }

// int main()
// {
//     //捕捉8号信号
//     //signal(SIGFPE, handler);
//     int a = 5;
//     a /= 0;

//     while (true)
//     {

//     }
//     return 0;
// }


// using func_t = function<void()>;
// vector<func_t> gFuncs;

// int gCount = 0;

// void handler(int signo)
// {
//     for (auto & f: gFuncs)
//     {
//         f();
//     }
//     cout << "gCount: " << gCount << endl;
//     alarm(1); // 重新设置闹钟
// }

// int main(int argc, char *argv[])
// {
//     gFuncs.push_back([]() {
//         cout << "我是一个内核持久化操作"  << endl;
//     });

//     gFuncs.push_back([]() {
//         cout << "我是一个下载任务"  << endl;
//     });

//     gFuncs.push_back([]() {
//         cout << "我是一个mysql任务"  << endl;
//     });

//     alarm(1);

//     signal(SIGALRM, handler);

//     while (true)
//     {
//         pause();
//         cout << "我醒来了..." << endl;
//         ++gCount;
//     }
//     return 0;
// }


// int number = 0;

// void die(int signumber)
// {
//     cout << "get a sig: " << signumber << " count: " << number << endl;
//     exit(0);
// }

// int main(int argc, char *argv[])
// {
//     alarm(3); 
//     sleep(1);
//     int n = alarm(0); // 取消闹钟

//     cout << n << endl;
//     return 0;
// }



// int main(int argc, char *argv[])
// {
//     alarm(1); // 1s之后收到SIGALRM信号
//     signal(SIGALRM, die);

//     while (true)
//     {
//         ++number;
//         //cout << "count: " << number++ << endl;
//     }
//     return 0;
// }

// int main()
// {
//     int cnt = 5;
//     while (true)
//     {
//         cout << "haha alive" << endl;
//         --cnt;
//         if (cnt == 0)
//         {
//             abort();
//         }
//         sleep(1);
//     }
//     return 0;
// }

// void Usage(string proc)
// {
//     cout << "Usage : " << proc << " signumber processid" << endl;
// }

// int main(int argc, char* argv[])
// {
//     if (argc != 3)
//     {
//         Usage(argv[0]);
//         exit(1);
//     }

//     int signumber = stoi(argv[1]);
//     pid_t id = stoi(argv[2]);

//     // 给对应进程发送信号
//     int n = ::kill(id, signumber);
//     if (n < 0)
//     {
//         // 杀死失败
//         perror("kill");
//         exit(2);
//     }

//     return 0;
// }

// void Handler(int signo)
// {
//     cout << "Get a signal number is: " << signo << endl;
// }

// int main()
// {
//     //注意这里是回调函数 传入的相当于函数地址
//     for (int signo = 1; signo < 32; ++signo)
//     {
//         signal(signo, Handler);
//         cout << "自定义捕捉信号: " << signo << endl;
//     }

//     while (true)
//     {
//         cout << "hello" << endl;
//         sleep(1);
//     }
//     return 0;
// }
